Common OS-Related Tasks
Now let’s look at some more OS-related tasks, while keeping our focus on SQL Server–related tasks.
Let’s check the status of the SQL Server service using the Get-Service cmdlet in the regular PowerShell console:
PS>Get-Service "mssqlserver"
Status Name DisplayName
------ ---- ------------
Stopped MSSQLSERVER SQL Server (MSSQLSERVER)
PS>
Note
When multiple instances are in use, the service name is something like MSSQL$INSTANCE01.
To start such an instance from PowerShell or even the SQL minishell,
you would have to use the following syntax for the service name: MSSQL`$INSTANCE01. The dollar sign ($)
character is escaped so that PowerShell doesn’t try to interpret this
as the beginning of a variable when the string is parsed.
The service is stopped. When you use the pipeline feature of PowerShell, the service is started:
PS>Get-Service "mssqlserver"|Start-Service
WARNING: Waiting for service 'SQL Server (SQLSERVER)
(MSSQLSERVER)' to finish starting...
WARNING: Waiting for service 'SQL Server (SQLSERVER)
(MSSQLSERVER)' to finish starting...
PS>
This example demonstrates using the pipeline to chain commands together. Alternatively, you could use Start-Service directly:
PS>Start-Service "mssqlserver"
The difference between the two methods demonstrates some of the power in PowerShell. When you use Get-Service, a service object is retrieved. When you use the pipeline, this object is passed to Start-Service. Start-Service
is built to basically accept input from the pipeline and autofills its
parameters based on what was input; thus, it knows to start the SQL
Server service.
Note
You could use SQL Server
PowerShell, but because SQL Server wasn’t started, Management Studio
would not have been able to connect, and you could not open SQL Server
PowerShell by right-clicking. You could use PowerShell to start sqlps.exe, though, and then you could use the Get-Service and Start-Service cmdlets to start SQL Server. If you use SQL Server PowerShell by calling sqlps.exe
directly from within a default PowerShell console, the SQL Server could
still be started, but a connection wouldn’t be automatically made to
the default instance of the database.
Most administrators
have probably already used the Windows Task Manager to look at the SQL
Server processes. Perhaps it was to determine whether SQL seemed to be
using too much memory or some other issue. PowerShell provides the Get-Process cmdlet, shown here, to look at running processes:
PS>Get-Process sqlservr
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s)
Id ProcessName
------- ------ ----- ----- ----- ------
-- ------------
318 45 64156 44288 1554 2.03
572 sqlservr
PS>
Another common OS-related task is to look for events in the Windows application event log:
PS>Get-EventLog Application -New 10
PS>Get-EventLog Application -New 10| `
Where {$_.EntryType -eq "Error"}
PS>Get-EventLog Application -New 10| `
Where {$_.EntryType -eq "Error"}|Select-Object TimeWritten
The
preceding example demonstrates another useful feature of the PowerShell
pipeline where you can join several commands together to get specific
results. First, only the 10 newest entries are retrieved; then a pipe is
used to get only the entries classified as an error, and finally, only
the TimeWritten property is displayed.
WMI is packed full of features that are useful for system
administration. A few examples of using PowerShell’s built-in WMI
features are shown here.
Getting a listing of all the fixed local logical drives:
PS>Get-WmiObject -query "select * from Win32_LogicalDisk where
DriveType='3'"
Getting a listing of all the fixed remote logical drives:
PS>Get-WmiObject -computerName server -query
"select * from Win32_LogicalDisk where DriveType='3'"
Getting a listing of all the local patches/hotfixes installed (the –computerName parameter could be used with a value to retrieve this information from a remote system):
PS>Get-WmiObject Win32_QuickFixEngineering
Note
Remote WMI connections may
require that appropriate firewall rules be open in the network and also
with a client firewall on the remote system. In addition, remote WMI
queries must also be authenticated. By default, WMI queries use the
current user’s authentication credentials. In some scenarios WMI
authentication can be more complicated.
The preceding examples show
only the beginning of all the things WMI can provide quick access to.
Another common task is trying to find files or folders. You can use the Get-ChildItem cmdlet to recursively search through a directory structure. The following example shows how to search for the location of the powershell.exe executable:
PS>Get-ChildItem c:\ -recurse powershell.exe
SQL Server–Specific Tasks
Before jumping into more
hardcore SQL Server PowerShell features, let’s briefly look at the SQL
Server event log. Fortunately, the log simply contains text-based files,
which PowerShell can read. You could use the Get-Content cmdlet to view the entire log, but instead you can use the Select-String
cmdlet to look for a specific string or pattern in the error log file.
First, you change the current location to the SQL Server log directory:
PS>Set-Location "C:\Program Files\Microsoft SQL Server"
PS>Set-Location (join-path $pwd "MSSQL10_50.MSSQLSERVER\MSSQL\Log")
PS>Select-String "error" ERRORLOG
The PowerShell prompt in the
preceding example is simply a generic one because the preceding
commands would work both in the default PowerShell console and in the
SQL Server PowerShell minishell.
An example of taking this further would be to retrieve all the errors in the ERRORLOG file. When you use Get-Member and Format-List to look at the object output by Select-String, the date is hidden inside a string in the Line property:
PS >
Select-String "error" ERRORLOG|foreach{$_.line}|where{$_ -match "^20*"}|
foreach{$date,$time=$_.split()[0],$_.split()[1];[datetime]$($date+" "+$time) }
PS >
The preceding example demonstrates how to look for the string "error" in the current SQL Server ERRORLOG file. For all the lines that match, the Line
property is passed along the pipeline. Next, based on some testing, it
appears that you want to search only lines that start with "20*-". From that object, two values are retrieved: $_.split()[0] and $_.split[1]. These values are placed in the $date and $time
variables, respectively. From there, they are recombined, and a type
accelerator is used to indicate that this is a date/time object, so any
calculations against this value will be simplified. What is finally
output is the time stamp showing when the error occurred.
Using the Provider
Using the SQL Server provider
can be very handy in navigating the system. Starting PowerShell from
SSMS, DBAs can easily find their way through different objects as if
working with files and directories.
When the SSMS is used to start
PowerShell at the server level, the databases are down one level, and
from there tables and users, for example, can also be easily accessed.
In the session shown in Figure 1, we navigated to a particular database and entered a dir Tables
command. The output from the last command would scroll beyond the
current screen, so only the first part of the output is displayed.